/*
    IceCode toolkit - config
    Copyright (C) 2011 Alfredo 'IceCoder' Mungo

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ICECODE_CONFIG
#define _ICECODE_CONFIG

#include <string>
#include <map>

namespace icecode {
  namespace config {

    /*
      DESCRIPTION:
       Contains, loads and saves (from file) a configuration.
       The configuration file must be a plain text file in the
       form: 'var_name: variable_content', can be commented by
       Adding a '#' character followed by the comment text.
       The '#' character can be added to variables by escaping
       it with a forward slash ('\') character. Empty lines
       are skipped. If a corrupted line is found (e.g. not in
       the form shown above), the error is reported to stderr
       and the line skipped.
       To delete a variable, delete its content by setting it
       to an empty string.
     */
    class Configuration {

      typedef std::pair<std::string, std::string> var;
      typedef std::map<std::string, std::string> var_container;

    public:
      /* Creates an empty configuration  */
      Configuration() {}

      /*
	DESCRIPTION:
	 Loads a configuration from file.

	EXCEPTIONS:
	 std::invalid_argument
	  File not found
      */
      explicit Configuration(std::string cfg_path);

      /*
	DESCRIPTION:
	 Returns an editable reference to the content of the indicated variable.
	 If no variable is found with that name, an empty variable is added and
	 it's reference returned.
       */
      std::string& operator [](std::string var_name);

      /*
	DESCRIPTION:
	 Saves the configuration to file.
	 If no file is specified, the internally stored path is used (if available).

	RETURN:
	 true
	  The configuration has been saved to file.
	 false
	  Error while opening file (check permissions and space).

	EXCEPTIONS:
	 std::invalid_argument
	  Invalid file name
      */
      bool save(std::string cfg_path = "");

    private:
      var_container vars;
      std::string path;
    };
  }
}

#endif //_ICECODE_CONFIG
